package parser;

import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;

public class Tool
{
    public static ArrayList<ClassRelation> total = new ArrayList<ClassRelation>();
    public static HashSet<String>          nodes = new HashSet<String>();

    public static void genTextFile(BufferedWriter textWriter)
    {
        try
        {
            for (int i = 0; i < total.size(); i++)
            {
                ClassRelation target = total.get(i);
                String[] useRelation = target.getUseRelation();
                String[] isRelation = target.getImplementsRelation();
                String[] hasRelation = target.getHasRelation();
                String[] extRelation = target.getExtendsRelation();
                String[] staticUseRelation = target.getStaticUseRelation();

                textWriter.write("*Class: " + target.getName() + "\n");

                textWriter.write("*Extends: \n");
                for (int k = 0; k < extRelation.length; k++)
                {
                    if (!nodes.contains(extRelation[k]))
                    {
                        continue;
                    }
                    textWriter.write("    " + extRelation[k] + "\n");
                }

                textWriter.write("*Implements: \n");
                for (int k = 0; k < isRelation.length; k++)
                {
                    if (!nodes.contains(isRelation[k]))
                    {
                        continue;
                    }
                    textWriter.write("    " + isRelation[k] + "\n");
                }

                textWriter.write("*Has: \n");
                for (int k = 0; k < hasRelation.length; k++)
                {
                    if (!nodes.contains(hasRelation[k]))
                    {
                        continue;
                    }
                    textWriter.write("    " + hasRelation[k] + "\n");
                }

                textWriter.write("*Use: \n");
                for (int k = 0; k < useRelation.length; k++)
                {
                    if (!nodes.contains(useRelation[k]))
                    {
                        continue;
                    }
                    textWriter.write("    " + useRelation[k] + "\n");
                }

                for (int k = 0; k < staticUseRelation.length; k++)
                {
                    if (!nodes.contains(staticUseRelation[k]))
                    {
                        continue;
                    }
                    textWriter.write("    " + staticUseRelation[k] + "\n");
                }

                textWriter
                        .write("------------------------------------------\n");
            }
            textWriter.flush();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void collectData(JavaNetParser parser)
    {
        try
        {
            ArrayList<ClassRelation> result = parser.getClassRelation();
            for (int i = 0; i < result.size(); i++)
            {
                ClassRelation target = result.get(i);

                String className = target.getName();
                if (nodes.contains(className))
                {
                    continue;
                }

                nodes.add(className);
                total.add(target);
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genXmlFile(BufferedWriter xmlWriter)
    {
        try
        {
            // write the header
            xmlWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            xmlWriter
                    .write("<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" ");
            xmlWriter
                    .write("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
            xmlWriter
                    .write("xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns ");
            xmlWriter
                    .write("http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n");
            xmlWriter
                    .write("<key id=\"label\" for=\"node\" attr.name=\"label\" attr.type=\"string\"/>\n");
            xmlWriter
                    .write("<key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\"/>\n");
            xmlWriter.write("<graph edgedefault=\"directed\">\n");

            // used to generate the unique id for the classes
            Hashtable<String, Integer> record = new Hashtable<String, Integer>();
            int basic = 0;

            // write the content
            Iterator<String> it = nodes.iterator();
            while (it.hasNext())
            {
                String tmp = it.next();
                xmlWriter.write("		<node id=\"");
                xmlWriter.write("n" + basic);
                xmlWriter.write("\">\n");

                xmlWriter.write("			<data key=\"label\">");
                xmlWriter.write(tmp);
                xmlWriter.write("</data>\n");

                xmlWriter.write("		</node>\n");

                // record the id
                record.put(tmp, new Integer(basic));
                basic++;
            }

            // write the edges
            int edge = 0;
            for (int i = 0; i < total.size(); i++)
            {
                ClassRelation target = total.get(i);
                String[] useRelation = target.getUseRelation();
                String[] isRelation = target.getImplementsRelation();
                String[] hasRelation = target.getHasRelation();
                String[] extRelation = target.getExtendsRelation();
                String[] staticUseRelation = target.getStaticUseRelation();

                HashSet<String> tmpRecord = new HashSet<String>();

                for (int k = 0; k < extRelation.length; k++)
                {
                    if (!nodes.contains(extRelation[k])
                            || tmpRecord.contains(extRelation[k]))
                    {
                        continue;
                    }

                    xmlWriter.write("	<edge id=\"e" + edge + "\"");
                    xmlWriter.write(" source=\"n"
                            + record.get(target.getName()).toString() + "\"");
                    xmlWriter.write(" target=\"n"
                            + record.get(extRelation[k]).toString() + "\">\n");
                    xmlWriter.write("		</edge>\n");

                    tmpRecord.add(extRelation[k]);
                    edge++;
                }

                for (int k = 0; k < isRelation.length; k++)
                {
                    if (!nodes.contains(isRelation[k])
                            || tmpRecord.contains(isRelation[k]))
                    {
                        continue;
                    }

                    xmlWriter.write("	<edge id=\"e" + edge + "\"");
                    xmlWriter.write(" source=\"n"
                            + record.get(target.getName()).toString() + "\"");
                    xmlWriter.write(" target=\"n"
                            + record.get(isRelation[k]).toString() + "\">\n");
                    xmlWriter.write("	</edge>\n");

                    tmpRecord.add(isRelation[k]);
                    edge++;
                }

                for (int k = 0; k < hasRelation.length; k++)
                {
                    if (!nodes.contains(hasRelation[k])
                            || tmpRecord.contains(hasRelation[k]))
                    {
                        continue;
                    }

                    xmlWriter.write("	<edge id=\"e" + edge + "\"");
                    xmlWriter.write(" source=\"n"
                            + record.get(target.getName()).toString() + "\"");
                    xmlWriter.write(" target=\"n"
                            + record.get(hasRelation[k]).toString() + "\">\n");
                    xmlWriter.write("	</edge>\n");

                    tmpRecord.add(hasRelation[k]);
                    edge++;
                }

                for (int k = 0; k < useRelation.length; k++)
                {
                    if (!nodes.contains(useRelation[k])
                            || tmpRecord.contains(useRelation[k]))
                    {
                        continue;
                    }

                    xmlWriter.write("	<edge id=\"e" + edge + "\"");
                    xmlWriter.write(" source=\"n"
                            + record.get(target.getName()).toString() + "\"");
                    xmlWriter.write(" target=\"n"
                            + record.get(useRelation[k]).toString() + "\">\n");
                    xmlWriter.write("	</edge>\n");

                    tmpRecord.add(useRelation[k]);
                    edge++;
                }

                for (int k = 0; k < staticUseRelation.length; k++)
                {
                    if (!nodes.contains(staticUseRelation[k])
                            || tmpRecord.contains(staticUseRelation[k]))
                    {
                        continue;
                    }

                    xmlWriter.write("	<edge id=\"e" + edge + "\"");
                    xmlWriter.write(" source=\"n"
                            + record.get(target.getName()).toString() + "\"");
                    xmlWriter.write(" target=\"n"
                            + record.get(staticUseRelation[k]).toString()
                            + "\">\n");
                    xmlWriter.write("	</edge>\n");

                    tmpRecord.add(staticUseRelation[k]);
                    edge++;
                }
            }

            // write the ending
            xmlWriter.write("</graph>\n");
            xmlWriter.write("</graphml>\n");

        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}